// import dotenv from 'dotenv';
import express from 'express';
import cors from 'cors';
// import mysql from 'mysql'
import session from 'express-session';

// import roleSystem from '../../shared/rolesystem.js'; // WARNING： Deprecated and will be removed in the future.
// import medicalRecord from '../../shared/medicalrecord.js'; // WARNING： Deprecated and will be removed in the future.

import recordRegistry from '../../shared/RecordRegistry.js'
import roleManager from '../../shared/RoleManager.js'
import signatureClaim from '../../shared/SignatureClaim.js'

import { fetchRecords } from './helper.js'

// import Panels from './panel-list.js';
import { ethers } from 'ethers';

dotenv.config({ path: './.env' });

const app = express();
const port = 3000;

// 配置session中间件
app.use(session({
    secret: process.env.SESSION_SECRET || 'secret-key', // 从环境变量获取或使用默认值
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        maxAge: 3600000 // 1小时
    }
}));

app.use(cors({
    origin: 'http://localhost:7001', // 前端地址
    credentials: true // 允许跨域携带凭证
}));

app.use(express.json());

app.listen(port, () => console.log('Start Server, listening on port 3000!'));

app.post('/api/login', async (req, res) => {
    const { signature, address } = req.body;

    console.log("Fetching role for address:", address);
    // 修改方法调用
    const role = await roleManager.methods.getRole(address).call();

    if (Number(role) === 0) { // Convert to number before comparison
        res.json({
            role: role.toString(),
            success: false
        });
        return;
    }

    // 将用户信息存入session
    req.session.user = {
        address,
        role: role.toString(), // Convert BigInt to string
        loggedInAt: Date.now()
    };

    res.json({
        role: role.toString(),
        success: true
    });
});

// 检查登录状态的端点
app.post('/api/check-auth', (req, res) => {
    console.log(req.session)
    if (!req.session.user) {
        console.log("Session not found.")
        res.json({
            isAuthenticated: false,
            address: null
        })
        return;
    }
    res.json({
        isAuthenticated: true
    });
});


// 检查登出端点
app.post('/api/logout', (req, res) => {
    req.session.destroy(err => {
        if (err) {
            return res.status(500).json({ error: '登出失败' });
        }
        res.clearCookie('connect.sid'); // 默认的session cookie名称
        res.json({ success: true });
    });
});

// 获取医疗记录下的导航栏信息
// 根据身份不同，显示新建表单、审批表单或所有
app.get('/api/v1/medical/nav', (req, res) => {
    // if (!req.session.user) {
    //   return res.status(401).json({ error: '未授权访问' });
    // }

});

app.get('/api/v1/user', (req, res) => {
    const { role } = req.session.user;
    const roles = [
        '未注册', '用户', '医院负责人', '保险公司负责人', '实验室负责人', '系统管理员'
    ];

    res.json({
        name: roles[role],
        avatar: 'https://space.coze.cn/api/coze_space/gen_image?image_size=square&prompt=professional%20doctor%20avatar&sign=ff6b4065316da742ed3122c9068f766f',
        role: roles[role]
    });
});

// 获取所有的表单信息，根据type返回：所有、待处理、已审批、已拒绝
app.get('/api/v1/medical/form', (req, res) => {

});


app.get('/api/v1/menuitems', (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }

    const { role } = req.session.user;

    const menuItems = {
        '0': [],
        '1': [1],
        '2': [],
        '3': [],
        '4': [1, 2, 3, 4],
        '5': [1, 2, 3, 4, 5]
    };

    res.setHeader('Content-Type', 'application/json');

    res.json({
        menuItems: menuItems[role] || menuItems['0']
    });
    return;
});

app.get('/api/v1/records', (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }
    const { role } = req.session.user;
    // 模拟数据
    const records = [
    ]

    res.json({ records });
});

// app.get('/api/v1/panels', (req, res) => {
//   if(!req.session.user) {
//     return res.status(401).json({ error: '未授权访问' });
//   }

//   res.json({Panels});
// });

app.post('/api/v1/role/assign', async (req, res) => {
    const { address, role } = req.body;

    try {
        if (!req.session.user) {
            return res.status(401).json({ error: '未授权访问' });
        }

        // console.log(req.session);

        roleManager.methods.assignRole(address, Number(role)).send({
            from: req.session.user.address, // 管理员地址
            gas: 2000000 // 适当调整
        })

        const targetRole = await roleManager.methods.getRole(address).call();
        // console.log("目标用户状态：", targetRole);

        if (Number(targetRole) === Number(role)) {
            res.json({
                success: true,
                message: '角色分配成功',
                role: Number(targetRole)
            });
        } else {
            res.json({
                success: false,
                message: '角色分配失败，无错误信息。'
            });
        }

    } catch (error) {
        console.error('角色分配错误:', error);
        res.status(500).json({
            success: false,
            message: error.message || '角色分配失败'
        });
    }
});

app.get('/api/v1/medical-records/options', (req, res) => {
    const { role } = req.session.user;

    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }

    const avaliableOptions = {
        '0': [],
        '1': [1],
        '2': [1, 2],
        '3': [1],
        '4': [1, 2]
    }

    res.json({
        options: avaliableOptions[role] || menuItems['0']
    });
});

app.post('/api/v1/medical-records/create', (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }

    const { address } = req.session.user;
    const { formData } = req.body;

    console.log("获取表单信息：", formData);

    // 转换日期格式（如果为空则使用当前时间戳）
    const recordTime = formData.date ? new Date(formData.date).getTime() / 1000 : Math.floor(Date.now() / 1000);

    recordRegistry.methods.createRecord(
        // address, // 患者地址
        formData.name.toString(), // 姓名 (string)
        formData.idNumber.toString(), // 身份证号 (string)
        formData.date.toString() || '', // 日期 （string）
        Number(formData.medicalType) || 0, // 医疗类型 (uint256)
        ethers.parseEther(formData.applyAmount), // 金额 (uint256) - 这里假设10 ETH
        formData.reason // 原因 (string)
    ).send({ from: address }) // 使用send而不是call，因为这是写入操作
        .then((receipt) => {
            console.log("交易收据:", receipt);
            res.json({
                success: true,
                message: '表单创建成功',
                transactionHash: receipt.transactionHash
            });
        })
        .catch((error) => {
            console.error("创建记录错误:", error);
            res.status(500).json({
                success: false,
                message: error.message || '表单创建失败'
            });
        });
})

app.get('/api/v1/medical-records/count', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }

    let count;
    try {
        count = await recordRegistry.methods.recordCount().call();
        // console.log("记录数量：", count);
    } catch (err) {
        console.error("获取记录数量错误:", err);
        res.status(500).json({
            success: false,
            message: err.message || '获取记录数量失败'
        });
        return;
    }

    res.json({
        success: true,
        count: Number(count)
    })
});

app.get('/api/v1/medical-records', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }
    const { address } = req.session.user;
    const { targetAddress } = req.query; // 默认limit=10，type=all
    const { page, size } = req.query;
    const { idNumber } = req.query;

    if (targetAddress) {
        // return res.status(400).json({ error: '无效的用户地址！' });
        try {
            // let record = {};
            recordRegistry.methods.getRecordByAddress(targetAddress).call()
                .then(async (result) => {
                    let records = [];

                    for (let recordId of result) {
                        const record = await recordRegistry.methods.getRecord(recordId).call();
                        console.log("获取到记录：", record);

                        await records.push({
                            id: recordId.toString(),
                            patientName: record.patientName,
                            idNumber: record.idNumber,
                            date: record.date,
                            medicalType: Number(record.medicalType),
                            applyAmount: record.applyAmount.toString(),
                            applyReason: record.applyReason,
                            status: Number(record.status)
                        });
                    }

                    res.json({
                        success: true,
                        records: records
                    })

                    return;
                })
                .catch((error) => {
                    console.error("获取记录错误:", error);
                    res.status(500).json({
                        success: false,
                        message: error.message || '获取记录失败'
                    });
                });
        } catch (error) {
            console.error('获取记录错误:', error);
            return res.status(500);
        }
    } else if (page && size) {
        const limit = Number(await recordRegistry.methods.recordCount().call());
        const start = (Number(page) - 1) * Number(size);
        const count = Number(size);
        // console.log("start:", start);
        // console.log("count:", count);

        try {
            // if (start >= limit) {
            //   return res.json({
            //     success: true,
            //     records: []
            //   })
            // } else if (start + count > limit) {
            //   count = limit - start;
            // }
            const records = await recordRegistry.methods.getRecordsByPage(Number(start), Number(count)).call();
            // console.log("获取到记录：", records);

            res.json({
                success: true,
                records: records.map((record) => {
                    return {
                        id: record.id,
                        patientName: record.patientName,
                        idNumber: record.patientId,
                        date: record.date,
                        medicalType: Number(record.medicalType),
                        applyAmount: record.applyAmount.toString(),
                        applyReason: record.applyReason,
                        status: Number(record.status)
                    }
                })
            })
        } catch (error) {
            console.error('获取记录错误:', error);
            return res.status(500);
        }
    } else if (idNumber) {

    } else {
        return res.status(400).json({ error: '无效的查询参数！' });
    }

});

app.get('/api/v1/medical-records/fetch', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }
    const { page = 1, size = 5, filter, searchTerm, type } = req.query;
    const pageNum = parseInt(page);
    const pageSize = parseInt(size);

    // console.log(type);

    try {
        // 1. 获取所有记录ID（单次合约调用）
        let allRecordIds = searchTerm
            ? await recordRegistry.methods.getRecordByIdNumber(searchTerm).call()
            : await recordRegistry.methods.getAllRecordId().call();

        // 2. 批量获取所有记录的状态（用于筛选）
        const filteredRecordIds = await Promise.all(
            allRecordIds.map(async (recordId) => {
                let record, medicalType;
                let status = -1;

                record = await recordRegistry.methods.getRecord(recordId).call();

                try {
                    status = await signatureClaim.methods.checkSignature(recordId).call()
                } catch (error) { }

                return {
                    recordId,
                    status: Number(status),
                    medicalType: Number(record.medicalType)
                };
            })
        );

        let matchedRecords = filteredRecordIds;
        if (filter) {
            matchedRecords = matchedRecords.filter(item => item.status === Number(filter));
        }
        if (type === 'hospital') {
            matchedRecords = matchedRecords.filter(item => item.medicalType !== 2);
            console.log("医院记录：", matchedRecords)
        } else if (type === 'lab') {
            // console.log("实验室记录：", matchedRecords)
            matchedRecords = matchedRecords.filter(item => item.medicalType === 2);
            // console.log("实验室记录：", matchedRecords)
        }

        const totalCount = matchedRecords.length;

        // 4. 计算分页范围
        const start = (pageNum - 1) * pageSize;
        const end = Math.min(start + pageSize, totalCount);

        // 5. 只获取当前页需要的记录ID
        const pageRecordIds = matchedRecords.slice(start, end).map(item => item.recordId);

        // 6. 批量获取当前页的记录数据
        const records = await Promise.all(
            pageRecordIds.map(async (recordId) => {
                const record = await recordRegistry.methods.getRecord(recordId).call();
                console.log("查找对应状态的记录：", matchedRecords.find(item => item.recordId === recordId), matchedRecords.find(item => item.recordId === recordId)?.status || -1)
                return {
                    id: recordId,
                    patientName: record.patientName,
                    idNumber: record.patientId,
                    date: record.date,
                    medicalType: Number(record.medicalType),
                    applyAmount: record.applyAmount.toString(),
                    applyReason: record.applyReason,
                    status: matchedRecords.find(item => item.recordId === recordId)?.status ?? -1
                };
            })
        );

        res.json({
            success: true,
            records: records,
            pagination: {
                currentPage: pageNum,
                pageSize: pageSize,
                totalItems: totalCount,
                totalPages: Math.ceil(totalCount / pageSize)
            }
        });

    } catch (error) {
        console.error('获取记录错误:', error);
        res.status(500).json({
            success: false,
            message: '获取记录失败'
        });
    }
});

// 在现有fetch接口附近添加
app.get('/api/v1/medical-records/fetch/:id', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }
    const { id } = req.params;

    let status = -1;

    try {
        status = await signatureClaim.methods.checkSignature(id).call();
    } catch (error) { }

    try {
        const record = await recordRegistry.methods.getRecord(id).call();
        res.json({
            success: true,
            record: {
                id,
                patientName: record.patientName,
                idNumber: record.patientId,
                date: record.date,
                medicalType: Number(record.medicalType),
                applyAmount: record.applyAmount.toString(),
                applyReason: record.applyReason,
                status: Number(status)
            }
        });
    } catch (error) {
        console.error('获取记录错误:', error);
        res.status(500).json({
            success: false,
            message: '获取记录失败'
        });
    }
});

app.post('/api/v1/medical-records/signature', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }
    const { recordId, approved } = req.body;

    if (!await signatureClaim.methods.canSignature(recordId).call()) {
        return res.json({
            success: false,
            message: '签名失败，记录已被处理或未找到！',
            status: approved
        });
    }

    try {
        const receipt = await signatureClaim.methods.signRecord(recordId, approved).send({
            from: req.session.user.address,
            gas: 2000000
        });

        // 直接从receipt中获取事件
        const event = receipt.events?.signedRecord;
        if (event && event.returnValues.recordId === recordId && event.returnValues.approved === approved) {
            res.json({
                success: true,
                message: '签名成功',
                status: approved
            });
        } else {
            throw new Error("签名状态无法查询！");
        }

    } catch (error) {
        console.error('签名时发生错误:', error);
        res.status(500).json({
            success: false,
            message: error.message || '签名时发生错误'
        });
    }
});

app.get('/api/v1/insurance/fetch', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }

    const { page = 1, size = 5, searchTerm, filter = -1 } = req.query;
    const pageNum = parseInt(page);
    const pageSize = parseInt(size);

    try {
        // 1. 获取所有记录ID（单次合约调用）
        let allRecordIds = searchTerm
            ? await recordRegistry.methods.getRecordByIdNumber(searchTerm).call()
            : await recordRegistry.methods.getAllRecordId().call();

        // 2. 批量获取所有记录的状态（用于筛选）
        const filteredRecordIds = await Promise.all(
            allRecordIds.map(async (recordId) => {
                let record, medicalType;
                let status = -1;

                record = await recordRegistry.methods.getRecord(recordId).call();

                try {
                    status = await signatureClaim.methods.checkClaim(recordId).call()
                } catch (error) { }

                return {
                    recordId,
                    status: Number(status),
                    medicalType: Number(record.medicalType)
                };
            })
        );
        const matchedRecords = filteredRecordIds.filter(item => item.status === Number(filter));

        console.log("保险公司记录：", matchedRecords)

        const totalCount = matchedRecords.length;

        // 4. 计算分页范围
        const start = (pageNum - 1) * pageSize;
        const end = Math.min(start + pageSize, totalCount);

        // 5. 只获取当前页需要的记录ID
        const pageRecordIds = matchedRecords.slice(start, end).map(item => item.recordId);

        // 6. 批量获取当前页的记录数据
        const records = await Promise.all(
            pageRecordIds.map(async (recordId) => {
                const record = await recordRegistry.methods.getRecord(recordId).call();
                return {
                    id: recordId,
                    patientName: record.patientName,
                    idNumber: record.patientId,
                    date: record.date,
                    medicalType: Number(record.medicalType),
                    applyAmount: record.applyAmount.toString(),
                    applyReason: record.applyReason,
                    status: matchedRecords.find(item => item.recordId === recordId)?.status || -1
                };
            })
        );

        res.json({
            success: true,
            records: records,
            pagination: {
                currentPage: pageNum,
                pageSize: pageSize,
                totalItems: totalCount,
                totalPages: Math.ceil(totalCount / pageSize)
            }
        });

    } catch (error) {
        console.error('获取记录错误:', error);
        res.status(500).json({
            success: false,
            message: '获取记录失败'
        });
    }
});

app.post('/api/v1/insurance/claim', async (req, res) => {
    if (!req.session.user) {
        return res.status(401).json({ error: '未授权访问' });
    }

    const { recordId, approved } = req.body;

    const record = await recordRegistry.methods.getRecord(recordId).call();

    console.log("确认请求有效...");
    if (!await signatureClaim.methods.canClaim(recordId).call()) {
        return res.json({
            success: false,
            message: '签名失败，记录已被处理或未找到！',
            status: approved
        });
    }

    console.log("签名中...");
    try {
        console.log("开始签名", recordId, approved);
        const receipt = await signatureClaim.methods.claimInsurance(recordId, approved, record.applyAmount).send({
            from: req.session.user.address,
            gas: 2000000
        });

        // 直接从receipt中获取事件
        console.log("查询状态...");
        const event = receipt.events?.claimedInsurance;
        if (event && event.returnValues.recordId === recordId && event.returnValues.approved === approved) {
            res.json({
                success: true,
                message: '操作成功',
                status: approved
            });
        } else {
            throw new Error("赔付状态无法查询！");
        }

    } catch (error) {
        console.error('赔付时发生错误:', error);
        res.status(500).json({
            success: false,
            message: error.message || '签名时发生错误'
        });
    }
});